package mil.af.amc.adpetracker.model;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import javax.persistence.*;
import java.util.*;

/**
 * Represents a DRMO package - items that are being turned in to DRMO
 *
 * Each package has a DTID, the date it was created, the date the items were
 * turned in, the item status (since servicable and unserviceable items
 * can't be in the same package), and the items that are part of the package.
 *
 * @author TSgt Jason Ferguson
 */

@Entity
@Table(name="T_DRMOPACKAGE")
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class DrmoPackage implements MappableEntity, Comparable<DrmoPackage> {

    private int id;
    private String dtid;
    private Date packageCreateDate;
    private Date turninDate;
    private Condition condition;
    private Set<EquipmentItem> identifiedItems = new HashSet<EquipmentItem>();
    private AdpeAccount adpeAccount;
    private DrmoPackageStatus status;

    public DrmoPackage() {

    }

    @Id
    @Column(name="DRMOPACKAGEID")
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Transient
    public String getName() {
        return this.getDtid();
    }

    @Column(name="DTID")
    public String getDtid() {
        return dtid;
    }

    public void setDtid(String dtid) {
        this.dtid = dtid;
    }

    @Column(name="CREATIONDATE")
    public Date getPackageCreateDate() {
        return packageCreateDate;
    }

    public void setPackageCreateDate(Date packageCreateDate) {
        this.packageCreateDate = packageCreateDate;
    }

    @Column(name="TURNINDATE")
    public Date getTurninDate() {
        return turninDate;
    }

    public void setTurninDate(Date turninDate) {
        this.turninDate = turninDate;
    }

/*    @ManyToOne
    @JoinColumn(name="ITEMCONDITIONID")
    public ItemCondition getItemCondition() {
        return itemCondition;
    }

    public void setItemCondition(ItemCondition itemCondition) {
        this.itemCondition = itemCondition;
    }*/

    @Enumerated(value=EnumType.ORDINAL)
    @Column(name="ITEMCONDITIONID")
    public Condition getCondition() {
        return condition;
    }

    public void setCondition(Condition condition) {
        this.condition = condition;
    }

//    @OneToMany
//    @JoinTable(name="T_DRMO_ITEM_LINK",
//            joinColumns=@JoinColumn(name="DRMOPACKAGEID"),
//            inverseJoinColumns = @JoinColumn(name="ITEMID"))
    @OneToMany(mappedBy = "drmoPackage")
    public Set<EquipmentItem> getIdentifiedItems() {
        return identifiedItems;
    }

    public void setIdentifiedItems(Set<EquipmentItem> identifiedItems) {
        this.identifiedItems = identifiedItems;
    }

    @Transient
    @OrderBy("serial")
    public List<EquipmentItem> getIdentifiedItemsList() {
        return new ArrayList<EquipmentItem>(this.identifiedItems);
    }

    @ManyToOne
    @JoinColumn(name="ADPEACCOUNTID")
    public AdpeAccount getAdpeAccount() {
        return adpeAccount;
    }

    public void setAdpeAccount(AdpeAccount adpeAccount) {
        this.adpeAccount = adpeAccount;
    }

    @Enumerated(value=EnumType.ORDINAL)
    @Column(name="PACKAGESTATUS")
    public DrmoPackageStatus getStatus() {
        return status;
    }

    public void setStatus(DrmoPackageStatus status) {
        this.status = status;
    }

    @Transient
    public int getPackageSize() {
        return identifiedItems.size();
    }

    @Transient
    public String getPackageType() {

        if (identifiedItems==null) {
            return "Undefined";
        }

        // Since I can't use get(0) on a set
        return ((EquipmentItem[]) identifiedItems.toArray())[0].getEquipmentType().getName();
    }

    @Transient
    public double getPackageValue() {

        if (identifiedItems==null || identifiedItems.size()==0) {
            return 0.0;
        }

        double value = 0.0;
        for (Iterator<EquipmentItem> it = identifiedItems.iterator(); it.hasNext();) {
            EquipmentItem item = it.next();
            value += item.getOriginalCost();
        }

        return value;
    }

    @Transient
    public Map toMap() {

        Map map = new HashMap();
        map.put("id", this.getId());
        map.put("name", this.getDtid());

        return map;
    }

    public int compareTo(DrmoPackage o) {
        return this.getDtid().toUpperCase().compareTo(o.getDtid().toUpperCase());
    }

}
